package org.compactmvc.viewpatterns
{
	import flash.display.Sprite;
	import flash.events.Event;
	
	import org.compactmvc.core.CompactMVC;
	
	/**
	 * The Abstract View Component Class registeres every view-component or view-helper together (if needed) with the appropriate View-Model (Mediator) with the wanted controller.
	 * Every registered model can also injected automatically on registration with the controller. 
	 * 
	 * @includeExample AbstractViewModelExample.as
	 * 
	 * @author Peter Krajnc
	 * 
	 */	
	public class AbstractViewComponent extends Sprite
	{
		protected var _controllerName:String;
		protected var _viewName:String;
		protected var _viewModelClassRef:Class;
		
		/**
		 * Constructor 
		 * @param viewName the unique view name
		 * @param viewModelClassRef the ViewModel Class Reference
		 * @param controllerName the Application Controller Name
		 * 
		 */		
		public function AbstractViewComponent(viewName:String, controllerName:String, abstractViewComponentModelClassRef:Class=null)
		{
			super();		
			_viewName = viewName;
			_viewModelClassRef = abstractViewComponentModelClassRef;
			_controllerName = controllerName;
			
			addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler, false, 0, true);
			
		}
		
		/**
		 * registers the view and the viewmodel with the controller automatically
		 * @param e
		 * 
		 */		
		private function addedToStageHandler(e:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
			addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler, false, 0, true);
			
			//register view model first
			if(_viewModelClassRef)
				CompactMVC.getInstance().core.registerViewModel( CompactMVC.getInstance().core.retrieveController(_controllerName), _viewModelClassRef.NAME, _viewModelClassRef, this);
			
			//register view
			CompactMVC.getInstance().registerView(_controllerName, _viewName, this);
			
			postRegisterHandler();
		}
		
		
		/**
		 * unregisters the view and model from the controller automatically
		 * @param e
		 * 
		 */		
		private function removedFromStageHandler(e:Event):void
		{
			removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
			
			//remove view model first
			if(_viewModelClassRef)
				CompactMVC.getInstance().core.removeViewModel( CompactMVC.getInstance().core.retrieveController(_controllerName),  _viewModelClassRef.NAME);
			
			//remove view
			CompactMVC.getInstance().removeView(_controllerName, _viewName);
			
			postRemoveHandler();
		}
		
		/**
		 * send a controller notification
		 * @param controllerName
		 * @param notificationType
		 * @param data
		 * 
		 */		
		protected function sendNotificationTo(controllerName:String, notificationType:String, data:Object=null):void 
		{	
			CompactMVC.getInstance().sendNotificationTo(controllerName, notificationType, data);
		}
		
		
		/**
		 * Called when the view has registered with the controller
		 * Your subclass should override this method if needed.
		 */
		protected function postRegisterHandler():void {}
		
		/**
		 * Called when the view has removed from the controller
		 * Your subclass should override this method if needed
		 */		
		protected function postRemoveHandler():void {}
		
		/**
		 * Called when the view transition has started
		 * Your subclass should override this method if needed
		 */
		protected function transitionStarted():void {}
		
		/**
		 * Called when the view transition has completed
		 * Your subclass should override this method if needed
		 */		
		protected function transitionCompleted():void {}
		
		/**
		 * returns the given View Name 
		 * @return 
		 * 
		 */		
		public function get viewName():String
		{
			return _viewName;
		}

		
	}
}